//
// Created by daybeha on 2022/7/7.
//

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

// 图像拼接
cv::Mat ImageSplicing(vector<cv::Mat> images,int type)
{
    if (type != 0 && type != 1)
        type = 0;

    int num = images.size();
    int newrow = 0;
    int newcol = 0;
    cv::Mat result;

    // 横向拼接
    if (type == 0)
    {
        int minrow = 10000;
        for (int i = 0; i < num; ++i)
        {
            if (minrow > images[i].rows)
                minrow = images[i].rows;
        }
        newrow = minrow;
        for (int i = 0; i < num; ++i)
        {
            int tcol = images[i].cols*minrow / images[i].rows;
            int trow = newrow;
            cv::resize(images[i], images[i], cv::Size(tcol, trow));
            newcol += images[i].cols;
            if (images[i].type() != images[0].type())
                images[i].convertTo(images[i], images[0].type());
        }
        result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));

        cv::Range rangerow, rangecol;
        int start = 0;
        for (int i = 0; i < num; ++i)
        {
            rangerow = cv::Range((newrow - images[i].rows) / 2, (newrow - images[i].rows) / 2 + images[i].rows);
            rangecol = cv::Range(start, start + images[i].cols);
            images[i].copyTo(result(rangerow, rangecol));
            start += images[i].cols;
        }
    }
        // 纵向拼接
    else if (type == 1) {
        int mincol = 10000;
        for (int i = 0; i < num; ++i)
        {
            if (mincol > images[i].cols)
                mincol = images[i].cols;
        }
        newcol = mincol;
        for (int i = 0; i < num; ++i)
        {
            int trow = images[i].rows*mincol / images[i].cols;
            int tcol = newcol;
            cv::resize(images[i], images[i], cv::Size(tcol, trow));
            newrow += images[i].rows;
            if (images[i].type() != images[0].type())
                images[i].convertTo(images[i], images[0].type());
        }
        result = cv::Mat(newrow, newcol, images[0].type(), cv::Scalar(255, 255, 255));

        cv::Range rangerow, rangecol;
        int start = 0;
        for (int i = 0; i < num; ++i)
        {
            rangecol= cv::Range((newcol - images[i].cols) / 2, (newcol - images[i].cols) / 2 + images[i].cols);
            rangerow = cv::Range(start, start + images[i].rows);
            images[i].copyTo(result(rangerow, rangecol));
            start += images[i].rows;
        }
    }

    return result;
}

int main(int argc, char *argv[])
{
    Py_SetProgramName(reinterpret_cast<wchar_t *>(argv[0]));

//    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
//    if (program == NULL) {
//        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
//        exit(1);
//    }
//    Py_SetProgramName(program);  /* optional but recommended */
//    Py_Initialize();
//    PyRun_SimpleString("from time import time,ctime\n"
//                       "print('Today is', ctime(time()))\n");
//    if (Py_FinalizeEx() < 0) {
//        exit(120);
//    }
//    PyMem_RawFree(program);
//    return 0;
//

    cv::Mat img0 = cv::imread("/home/daybeha/Documents/Dataset/Kitti/sequences/00/image_0/000000.png",cv::IMREAD_GRAYSCALE);
    cv::Mat img1 = cv::imread("/home/daybeha/Documents/Dataset/Kitti/sequences/00/image_0/000020.png",cv::IMREAD_GRAYSCALE);
////    show_com_img(img0,img1);
//    vector<cv::Mat> imgs;
//    imgs.emplace_back(img0);
//    imgs.emplace_back(img1);
//    cv::Mat con_img = ImageSplicing(imgs,0);
//    cv::imshow("con_img", con_img);
//    cv::waitKey();



    PyObject *pName, *pModule, *pFunc;
    PyObject *pArgs, *pValue;
    int i;

    if (argc < 3) {
        fprintf(stderr,"Usage: call pythonfile funcname [args]\n");
        return 1;
    }

    Py_Initialize();
//    PyRun_SimpleString("#!/usr/include/python3\n");
    PyRun_SimpleString("print ('Hello Python!')\n");
    PyRun_SimpleString("from time import time,ctime\n"
                       "print('Today is', ctime(time()))\n");

    PyRun_SimpleString("import platform\n"
                       "print(f\"Python Version: {platform.python_version()}\")\n");


    // 将Python工作路径切换到待调用模块所在目录，一定要保证路径名的正确性
    string path = "/home/daybeha/Documents/github/DeepLabV3_ws/src/superglue/script";
    string chdir_cmd = string("sys.path.append(\"") + path + "\")";

//    const char* cstr_cmd = chdir_cmd.c_str();
    PyRun_SimpleString("import sys\n");
    PyRun_SimpleString(chdir_cmd.c_str());
    PyRun_SimpleString("print(sys.path)");

    // agrv[1] 为 python脚本
    pName = PyUnicode_DecodeFSDefault(argv[1]);


    /* Error checking of pName left out */
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    if (pModule != NULL) {
        // argv[2] 为 指定的函数
        pFunc = PyObject_GetAttrString(pModule, argv[2]);
//        pFunc = PyObject_GetAttrString(pModule, "great_func");

        /* pFunc is a new reference */
        if (pFunc && PyCallable_Check(pFunc)) {
            pArgs = PyTuple_New(argc - 3);
            for (i = 0; i < argc - 3; ++i) {
                pValue = PyLong_FromLong(atoi(argv[i + 3]));
                if (!pValue) {
                    Py_DECREF(pArgs);
                    Py_DECREF(pModule);
                    fprintf(stderr, "Cannot convert argument\n");
                    return 1;
                }
                /* pValue reference stolen here: */
                PyTuple_SetItem(pArgs, i, pValue);
            }
            pValue = PyObject_CallObject(pFunc, pArgs);
            Py_DECREF(pArgs);
            if (pValue != NULL) {
                printf("Result of call: %ld\n", PyLong_AsLong(pValue));
                Py_DECREF(pValue);
            }
            else {
                Py_DECREF(pFunc);
                Py_DECREF(pModule);
                PyErr_Print();
                fprintf(stderr,"Call failed\n");
                return 1;
            }
        }
        else {
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        PyErr_Print();
        fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
        return 1;
    }

    if (Py_FinalizeEx() < 0) {
        return 120;
    }
    return 0;

}